
#ifndef __PARAMLINE_H__
#define __PARAMLINE_H__

#include "MathDef.h"
#include "Vector.h"

//
template<int dimension>
class CParamLine
{
public:

	typedef CVector<dimension>	CParmPoint, CParamVector;
	
	CParamLine()
	{
	}

	CParamLine(CParmPoint& init, CParmPoint& term)
	:m_p0(init), m_p1(term), m_v(init, term)
	{
	}

	CParamLine(CParmPoint* pInit, CParmPoint* pTerm)
	:m_p0(*pInit), m_p1(*pTerm), m_v(*pTerm, *pInit)
	{
	}

	CParamLine(float* p_init, float* p_term)
	:m_p0(p_init), m_p1(p_term), m_v(p_term, p_init)
	{
		// this initializes a parametric 2d line, note that the function
		// computes v=p_pend - p_init, thus when t=0 the line p=p0+v*t = p0
		// and whne t=1, p=p1, this way the segement is traced out from
		// p0 to p1 via 0<= t <= 1
	}

	virtual ~CParamLine()
	{
	}


	int Init(CParmPoint& init, CParamVector& term)
	{
		m_p0 = init;
		m_p1 = term; 
		m_v.Build(init, term);

		return 0;
	}

	int Init(CParmPoint* pInit, CParamVector* pTerm)
	{
		m_p0 = *pInit;
		m_p1 = *pTerm; 
		m_v.Build(*pInit, *pTerm);

		return 0;
	}

	int Init(float* p_init, float* p_term)
	{
		m_p0 = p_init;
		m_p1 = p_term;
		m_v.Build(p_init, p_term);

		return 0;
	}

	CParmPoint* GetP0()
	{
		return &m_p0;
	}

	CParmPoint* GetP1()
	{
		return &m_p1;
	}

	CParamVector* GetV()
	{
		return &m_v;
	}

	int Compute_Parm_Line(float t, CParmPoint* pt);

	int	Intersect(CParamLine& rhs, float *t1, float *t2);

protected:

	CParmPoint		m_p0; // start point of parametric line
	CParmPoint		m_p1; // end point of parametric line
	CParamVector	m_v;  // direction vector of line segment
};

typedef CParamLine<2>	CParamLine2d;
typedef CParamLine<3>	CParamLine3d;


//class CParamLine2d
//{
//public:
//	
//	CParamLine2d()
//	{
//	}
//
//	CParamLine2d(CPoint2d& init, CVector2d& term)
//	:m_p0(init), m_p1(term), m_v(init, term)
//	{
//	}
//
//	CParamLine2d(CPoint2d* pInit, CVector2d* pTerm)
//	:m_p0(*pInit), m_p1(*pTerm), m_v(*pTerm, *pInit)
//	{
//	}
//
//	CParamLine2d(POINT2D_PTR p_init, POINT2D_PTR p_term)
//	:m_p0(p_init->M), m_p1(p_term->M), m_v(p_term->M, p_init->M)
//	{
//		// this initializes a parametric 2d line, note that the function
//		// computes v=p_pend - p_init, thus when t=0 the line p=p0+v*t = p0
//		// and whne t=1, p=p1, this way the segement is traced out from
//		// p0 to p1 via 0<= t <= 1
//	}
//
//	virtual ~CParamLine2d()
//	{
//	}
//
//
//	int Init(CPoint2d& init, CVector2d& term)
//	{
//		m_p0 = init;
//		m_p1 = term; 
//		m_v.Build(init, term);
//
//		return 0;
//	}
//
//	int Init(CPoint2d* pInit, CVector2d* pTerm)
//	{
//		m_p0 = *pInit;
//		m_p1 = *pTerm; 
//		m_v.Build(*pInit, *pTerm);
//
//		return 0;
//	}
//
//	int Init(POINT2D_PTR p_init, POINT2D_PTR p_term)
//	{
//		m_p0 = p_init->M;
//		m_p1 = p_term->M; 
//		m_v.Build(p_init->M, p_term->M);
//
//		return 0;
//	}
//
//	int Compute_Parm_Line2D(float t, CPoint2d* pt)
//	{
//		// this function computes the value of the sent parametric 
//		// line at the value of t
//
//		pt->SetX(m_p0[X] + m_v[X] * t);
//		pt->SetY(m_p0[Y] + m_v[Y] * t);
//
//		return 0;
//
//	} // end Compute_Parm_Line2D
//
//protected:
//
//	CPoint2d		m_p0; // start point of parametric line
//	CPoint2d		m_p1; // end point of parametric line
//	CVector2d		m_v;  // direction vector of line segment
//};


//class CParamLine3d
//{
//public:
//	
//	CParamLine2d()
//	{
//	}
//
//	CParamLine2d(CPoint2d& init, CVector2d& term)
//	:m_p0(init), m_p1(term), m_v(init, term)
//	{
//	}
//
//	CParamLine2d(CPoint2d* pInit, CVector2d* pTerm)
//	:m_p0(*pInit), m_p1(*pTerm), m_v(*pTerm, *pInit)
//	{
//	}
//
//	CParamLine2d(POINT2D_PTR p_init, POINT2D_PTR p_term)
//	:m_p0(p_init->M), m_p1(p_term->M), m_v(p_term->M, p_init->M)
//	{
//		// this initializes a parametric 2d line, note that the function
//		// computes v=p_pend - p_init, thus when t=0 the line p=p0+v*t = p0
//		// and whne t=1, p=p1, this way the segement is traced out from
//		// p0 to p1 via 0<= t <= 1
//	}
//
//	virtual ~CParamLine2d()
//	{
//	}
//
//
//	int Init(CPoint2d& init, CVector2d& term)
//	{
//		m_p0 = init;
//		m_p1 = term; 
//		m_v.Build(init, term);
//
//		return 0;
//	}
//
//	int Init(CPoint2d* pInit, CVector2d* pTerm)
//	{
//		m_p0 = *pInit;
//		m_p1 = *pTerm; 
//		m_v.Build(*pInit, *pTerm);
//
//		return 0;
//	}
//
//	int Init(POINT2D_PTR p_init, POINT2D_PTR p_term)
//	{
//		m_p0 = p_init->M;
//		m_p1 = p_term->M; 
//		m_v.Build(p_init->M, p_term->M);
//
//		return 0;
//	}
//
//	int Compute_Parm_Line2D(float t, CPoint2d* pt)
//	{
//		// this function computes the value of the sent parametric 
//		// line at the value of t
//
//		pt->SetX(m_p0[X] + m_v[X] * t);
//		pt->SetY(m_p0[Y] + m_v[Y] * t);
//
//		return 0;
//
//	} // end Compute_Parm_Line2D
//
//protected:
//
//	CPoint3d		m_p0; // start point of parametric line
//	CPoint3d		m_p1; // end point of parametric line
//	CVector3d		m_v;  // direction vector of line segment
//};


#endif